Превод на 24-core CPU and I can’t move my mouseВсичко започна,

...
Превод на 24-core CPU and I can’t move my mouseВсичко започна,
Коментари Харесай

24-ядрен процесор, а не мога да помръдна курсора на мишката

Превод на 24-core CPU and I can’t move my mouse

Всичко стартира, когато моят компютър стартира да се забавя. А това е моят работен компютър с Windows 10 и 24-ядрен (48 потока) процесор, претрупан до към 50%. Бързият SSD съвсем не се използваше. И въпреки всичко, когато помръднах мишката, курсорът не реагира незабавно. Имах случаи на лагване с дълготрайност няколко секунди.

И този път направих това, което върша във всички сходни случаи – записах и трасирах събитията благодарение на ETW (Event Tracing for Windows). И да, открих бъг в Оценка за съвместимост Windows 10, съществено влияещ на продуктивността при завършването на процесите.

Трасирането благодарение на ETW сподели, че потребителският интерфейс (UI) се срутва в редица стратегии. Започнах с проучването на 1,125-секундното забавяне на курсора в диспечера на дилемите Task Manager:

По-долният скрийншот демонстрира потреблението на процесора от операционната система по време на този лаг. Процесите се виждат, само че и добре се вижда, че процесорът съвсем не се натоварва над 50%.

Таблицата CPU Usage (Precise) демонстрира, че UI потокът на диспечера на дилемите непрекъснато се блокира от извикванията на функционалността SendMessageW, която очевидно изчаква в сериозна зона на ядрото, надълбоко в стека на извикванията win32kbase.sys!EnterCrit (тук това не е показано).

Ръчно прекосих по цялата верига на изчакванията и отметнах десетки процеси, с цел да намеря, кой изяжда ресурсите на потребителския интерфейс. Получи се следното:

Taskmgr.exe (72392) увисва на 1,125 секунда (MsgCheckDelay) на нишката 69,196. Най-голямо закъснение от 115,6 ms внася win32kbase.sys!EnterCrit, квалифициран за осъществяване от процеса conhost.exe (16264) на нишка 2560 в точка 3.273101862. След това conhost.exe (16264), 2560 е квалифициран за 3.273077782 след изчакване на 115 640,966 ms от процеса mstsc.exe (79392), 71272. От своя страна mstsc.exe е квалифициран (същото време на забавяне) от процеса UIforETW.exe (78120), 79584, който пък е квалифициран от процеса conhost.exe (16264), 58696, който от своя страна е квалифициран от процеса gomacc.exe (93668), 59948, квалифициран от процеса gomacc.exe (95164), 76844.

Отказах се да не преставам, тъй като множеството процеси преустановяват блокажа единствено след няколко микросекунди. Но в последна сметка открих няколко процеса (процесите gomacc.exe) които задържат блокировката няколко стотици микросекунди. Или може да се каже, че те са готови от някой, който задържа блокировката, а след няколко микросекунди те приготвят различен развой за нейното спиране. Всички тези процеси смъкват блокировката в границите на NtGdiCloseProcess.

Омръзна ми ръчно да наблюдавам всички тези процеси на изчаквания и взех решение да прегледам, до каква степен постоянно се среща този стек с извиквания. Това стана, като реалокирах колонката Ready Thread Stack наляво и потърсих в нея NtGdiCloseProcess. След това използвах опцията View Callers -> By Function във WPA, с цел да видя всички стекове Ready Thread Stacks с тази функционалност. Родителските стекове са показани по-долу:

Програмата изброи 5768 контекстни превключвания, до момента в който процесът NtGdiCloseProcess се намира в стека Ready Thread Stack, като всяко едно от тях отбелязва момента, когато се освобождава сериозна секция. Взети дружно, потоците в тези стекове, съхраняващи извикванията, изчакват общо 63,3 секунди – много впечатляващо спрямо следения от мен лаг от 1,125 секунди. Ако всяко от тези събития протича откакто потока задържа блокирането единствено с 200 микросекунди, получава се точно забавянето на интерфейса с 1,125 секунди.

Тази част на Windows не ми е изключително позната, само че съчетанието PspExitThread и NtGdiCloseProcess ясно демонстрира, че това държание се демонстрира при завършването на процеса.

Всичко това се случи по време на компилирането на Chrome, а това поражда в действителност доста процеси. А и аз използвах нашата фирмена разпределена система за компилиране, която основава доста процеси, само че и ги приключва доста бързо.

Следващата стъпка бе да пресметна, какъв брой тъкмо време е минало и изгубено вътре в NtGdiCloseProcess. Пренесох таблицата CPU Usage (Sampled) във WPA, с цел да прегледам извикванията на NtGdiCloseProcess. В скрийншота по-долу се вижда, че от 1,125 секундния лаг. към 1085 милисекунди са изразходвани от процеса NtGdiCloseProcess, а това са 96% от цялото време:

А това е прекомерно неприятно – по какъв начин може 96% от времето да бъде изразходвано от една функционалност и да не остане време за проявление на известия и с цел да се обнови местоположението на курсора. Задълбочих се в този проблем и взех решение да направя опит. Написах тестова стратегия, която с оптималната скорост основава 1000 процеса, изчаква 0,5 секунди и по-късно подава команда за едновременното довеждане докрай на всички тези процеси. В по-долния скрийншот е показано действието на тази стратегия на моя домакински преносим компютър с 4-ядрен (8 потока) процесор:

Да разгледаме тази диаграма. Създаването на процеси е лимитирано от опциите на процесора и това е в реда на нещата. Но прекъсването на процесите се лимитира от процесора единствено първоначално и края (червените пикове в дясната част, показваща прекъсването на процесите). Съвсем ясно се вижда, че в средата има един огромен интервал (около една секунда), където логаритъмът се обработва поредно и се употребява единствено един от осемте налични потока в системата. Да си напомним, че моята стратегия сътвори 1000 процеса и всички те се борят за единствената блокировка, намираща се в NtGdiCloseProcess. Това е сериозен проблем. Именно този интервал демонстрира времето на лага, когато стратегиите мощно се забавят, а придвижванията на курсора съвсем стопират. Понякога това закъснение се разтяга до няколко секунди.

Забелязах че казусът се задълбочава, когато компютърът е работил известно време. Разбира се, рестартирах компютъра и още веднъж пуснах своята тестова стратегия. Спирането на процесите не бе толкоз тежко, само че казусът си остана даже и в одеве стартираната машина.



И тук се сетих за нещо друго. Стартирах своята стратегия на старичък компютър от 2008 година с Windows 7 и Intel Core 2 Q8200. Резултатите са напълно съвсем други:

Създаването на нови процеси става по-бавно, както може да се чака от един доста по-слаб процесор. Но тяхното прекъсване и довеждане докрай става даже малко по-бързо от моя нов преносим компютър със стабилен процесор. Но по-важното е, че всичко става напълно редом и няма престояване на потоци. Това се вижда в дясната страна на изображението, показващо прекъсването на процесите – интервал изцяло липсва.

Това демонстрира, че неналичието на редом привършване на процесите е нов проблем, появил се някъде сред Windows 7 и Windows 10.
48 потока, а 47 от тях бездействат
Законът на Амдал гласи, че в случай че разпределите своя логаритъм да се извършва на няколко процесорни ядра, то сумарното време на неговото осъществяване зависи от времето на осъществяване на най-дългия откъс, който не може да се разпаралели. Когато интензивно употребявам своя работен компютър в продължение на няколко дни, казусът се изявява все по-явно, а огромният брой ядра с нищо не оказва помощ. За да ускоря компилацията и през това време курсорът да се движи и интерфейсът да реагира, би трябвало да рестартирам машината всеки ден. Но при проявата на този противен бъг, натоварването на процесора съвсем не минава 50%, а дискът не се употребява. Връщането към Windows 7 стартира да ми наподобява все по-привлекателно.

Всъщност, прибавянето на процесорни ядра в моята компютърна система забавя скоростта на реакция на потребителския интерфейс. Просто компилирането на Chrome поражда доста процеси, а в случай че имате повече ядра, толкоз повече процеси ще се борят за приключването на работата си. Тоест, май вместо да споделям „24-ядрен процесор, а не мога да помръдна курсора на мишката“ е по-добре да кажа „24-ядрен процесор и по тази причина не мога да мръдна курсора на мишката„.

Съобщихме за този проблем на Microsoft и в този момент програмистите оглеждат нещата
И още нещо…
Ето по какъв начин наподобява моята тестова стратегия на моя мощен 24-ядрен компютър:



Виждате ли дребната алена линия в долния десен ъгъл? Това е нагледна проява на закона на Амдал, когато 98% от ресурсите на машината престояват съвсем две секунди, тъй като процедурата по довеждане докрай на процесите употребява единствено един поток и не може да ги спре. А аз не мога да помръдна курсора на мишката.
Източник: kaldata.com

СПОДЕЛИ СТАТИЯТА


Промоции

КОМЕНТАРИ
НАПИШИ КОМЕНТАР